//@author A0087191Y
package net.mysoc.w111j.service;

import java.util.Deque;
import java.util.LinkedList;

import net.mysoc.w111j.service.actions.Action;

/**
 * The {@code UndoManager} manages a history of actions that can be undone.
 */
public class UndoManager {
    /** The undo history */
    private final Deque<Action> undoStack;
    /** The current status string. */
    private String status;
    /** Whether {@code undo} was called last. */
    private boolean lastActionUndo;

    /** Constructs a new {@code UndoManager} with empty history. */
    public UndoManager() {
        undoStack = new LinkedList<>();
        status = "";
        lastActionUndo = false;
    }

    /** Undoes the most recent undoable {@code Action}. */
    public void undo() {
        if (!canUndo()) {
            throw new IllegalStateException("Undo stack is empty.");
        }
        Action lastAction = undoStack.pop();
        lastAction.undo();
        status = lastAction.getStatus();
        lastActionUndo = true;
    }

    /**
     * Checks whether there is anything to undo.
     *
     * @return whether there is anything to undo.
     */
    public boolean canUndo() {
        return !undoStack.isEmpty();
    }

    /**
     * Appends a new {@code Action} to the undo history.
     *
     * @param action the {@code Action} to add.
     */
    public void addAction(Action action) {
        undoStack.push(action);
        status = action.getStatus();
        lastActionUndo = false;
    }

    /**
     * Gets the current status.
     *
     * @return the current status string.
     */
    public String getStatus() {
        return lastActionUndo ? "Undo: " + status : status;
    }
}
